OPC Studio User's Guide and Reference
Examples - OPC XML-DA - Get values of multiple properties

Basic Example

// This example shows how to get value of multiple OPC XML-DA properties, and handle errors.
//
// Note that some properties may not have a useful value initially (e.g. until the item is activated in a group), which also the
// case with Timestamp property as implemented by the demo server. This behavior is server-dependent, and normal. You can run 
// IEasyDAClient.ReadMultipleItemValues.Main.vbs shortly before this example, in order to obtain better property values. Your 
// code may also subscribe to the items in order to assure that they remain active.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

using System;
using OpcLabs.BaseLib.OperationModel;
using OpcLabs.EasyOpc;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.OperationModel;

namespace DocExamples.DataAccess.Xml
{
    partial class GetMultiplePropertyValues
    {
        public static void Main1Xml()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();

            ServerDescriptor serverDescriptor = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx";

            // Get the values of Timestamp and AccessRights properties of two items.
            ValueResult[] results = client.GetMultiplePropertyValues(new[]
            {
                new DAPropertyArguments(serverDescriptor, "Dynamic/Analog Types/Int", DAPropertyDescriptor.Timestamp),
                new DAPropertyArguments(serverDescriptor, "Dynamic/Analog Types/Int", DAPropertyDescriptor.AccessRights),
                new DAPropertyArguments(serverDescriptor, "Static/Analog Types/Double", DAPropertyDescriptor.Timestamp),
                new DAPropertyArguments(serverDescriptor, "Static/Analog Types/Double", DAPropertyDescriptor.AccessRights)
            });

            for (int i = 0; i < results.Length; i++)
            {
                ValueResult valueResult = results[i];
                if (valueResult.Exception is null)
                    Console.WriteLine($"results({i}).Value: {valueResult.Value}");
                else
                    Console.WriteLine($"results({i}).Exception.Message: {valueResult.Exception.Message}");
            }
        }
    }
}
# This example shows how to get value of multiple OPC XML-DA properties, and handle errors.

# Note that some properties may not have a useful value initially (e.g. until the item is activated in a group), which also the
# case with Timestamp property as implemented by the demo server. This behavior is server-dependent, and normal. You can run 
# IEasyDAClient.ReadMultipleItemValues.Main.vbs shortly before this example, in order to obtain better property values. Your 
# code may also subscribe to the items in order to assure that they remain active.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc

# Import .NET namespaces.
from OpcLabs.EasyOpc import *
from OpcLabs.EasyOpc.DataAccess import *
from OpcLabs.EasyOpc.DataAccess.OperationModel import *


# Instantiate the client object.
client = EasyDAClient()

serverDescriptor = ServerDescriptor('http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx')

# Get the values of Timestamp and AccessRights properties of two items.
results = client.GetMultiplePropertyValues(
    [
        DAPropertyArguments(serverDescriptor, DANodeDescriptor('Dynamic/Analog Types/Int'), DAPropertyDescriptor.Timestamp),
        DAPropertyArguments(serverDescriptor, DANodeDescriptor('Dynamic/Analog Types/Int'), DAPropertyDescriptor.AccessRights),
        DAPropertyArguments(serverDescriptor, DANodeDescriptor('Static/Analog Types/Double'), DAPropertyDescriptor.Timestamp),
        DAPropertyArguments(serverDescriptor, DANodeDescriptor('Static/Analog Types/Double'), DAPropertyDescriptor.AccessRights)
    ])

for i, valueResult in enumerate(results):
    if valueResult.Exception is None:
        print('results[', i, '].Value: ', valueResult.Value, sep='')
    else:
        print('results[', i, '].Exception.Message: ', valueResult.Exception.Message, sep='')
' This example shows how to get value of multiple OPC XML-DA properties, and handle errors.
'
' Note that some properties may not have a useful value initially (e.g. until the item Is activated in a group), which also the
' case with Timestamp property as implemented by the demo server. This behavior is server-dependent, and normal. You can run 
' IEasyDAClient.ReadMultipleItemValues.Main.vbs shortly before this example, in order to obtain better property values. Your 
' code may also subscribe to the items in order to assure that they remain active.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

Imports OpcLabs.BaseLib.OperationModel
Imports OpcLabs.EasyOpc
Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.OperationModel

Namespace DataAccess.Xml
    Partial Friend Class GetMultiplePropertyValues
        Shared Sub Main1Xml()
            ' Instantiate the client object.
            Dim client = New EasyDAClient()

            Dim serverDescriptor As ServerDescriptor = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx"

            ' Get the values of Timestamp and AccessRights properties of two items.
            Dim results() As ValueResult = client.GetMultiplePropertyValues(New DAPropertyArguments() {
                New DAPropertyArguments(serverDescriptor, "Dynamic/Analog Types/Int", DAPropertyDescriptor.Timestamp),
                New DAPropertyArguments(serverDescriptor, "Dynamic/Analog Types/Int", DAPropertyDescriptor.AccessRights),
                New DAPropertyArguments(serverDescriptor, "Static/Analog Types/Double", DAPropertyDescriptor.Timestamp),
                New DAPropertyArguments(serverDescriptor, "Static/Analog Types/Double", DAPropertyDescriptor.AccessRights)
             })

            For i = 0 To results.Length - 1
                Dim valueResult As ValueResult = results(i)
                If valueResult.Exception Is Nothing Then
                    Console.WriteLine($"results({i}).Value: {valueResult.Value}")
                Else
                    Console.WriteLine($"results({i}).Exception.Message: {valueResult.Exception.Message}")
                End If
            Next i

        End Sub

    End Class
End Namespace

Example combined with item browsing

The example below is a bit more complex, and combines the ability to browse for items with getting the the data type property for each of the items obtained, for OPC XML-DA Servers.

.NET

// This example shows how to obtain a data type of all OPC XML-DA items under a branch.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

using System;
using System.Linq;
using OpcLabs.BaseLib.ComInterop;
using OpcLabs.BaseLib.OperationModel;
using OpcLabs.EasyOpc;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.AddressSpace;

namespace DocExamples.DataAccess.Xml
{
    partial class GetMultiplePropertyValues
    {
        public static void DataTypeXml()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();

            ServerDescriptor serverDescriptor = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx";

            // Browse for all leaves under the "Static/Analog Types" branch
            DANodeElementCollection nodeElementCollection = client.BrowseLeaves(serverDescriptor, "Static/Analog Types");

            // Create list of node descriptors, one for each leaf obtained
            DANodeDescriptor[] nodeDescriptorArray = nodeElementCollection
                .Where(element => !element.IsHint)  // filter out hint leafs that do not represent real OPC items (rare)
                .Select(element => new DANodeDescriptor(element))
                .ToArray();

            // Get the value of DataType property; it is a 16-bit signed integer
            ValueResult[] valueResultArray = client.GetMultiplePropertyValues(serverDescriptor,
                nodeDescriptorArray, DAPropertyIds.DataType);

            for (int i = 0; i < valueResultArray.Length; i++)
            {
                DANodeDescriptor nodeDescriptor = nodeDescriptorArray[i];

                // Check if there has been an error getting the property value
                ValueResult valueResult = valueResultArray[i];
                if (!(valueResult.Exception is null))
                {
                    Console.WriteLine("{0} *** Failure: {1}", nodeDescriptor.NodeId, valueResult.Exception.Message);
                    continue;
                }

                // Convert the data type to VarType
                var varType = (VarType)(short)valueResult.Value;

                // Display the obtained data type
                Console.WriteLine("{0}: {1}", nodeDescriptor.ItemId, varType);
            }
        }
    }
}
# This example shows how to obtain a data type of all OPC XML-DA items under a branch.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc

# Import .NET namespaces.
from OpcLabs.BaseLib.ComInterop import *
from OpcLabs.EasyOpc import *
from OpcLabs.EasyOpc.DataAccess import *
from OpcLabs.EasyOpc.DataAccess.OperationModel import *
from OpcLabs.EasyOpc.OperationModel import *


serverDescriptor = ServerDescriptor('http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx')

# Instantiate the client object.
client = EasyDAClient()

# Browse for all leaves under the "Static/Analog Types" branch
try:
    nodeElementCollection = IEasyDAClientExtension.BrowseLeaves(client,
                                                                serverDescriptor,
                                                                DANodeDescriptor('Static/Analog Types'))
except OpcException as opcException:
    print('*** Failure: ' + opcException.GetBaseException().Message)
    exit()

# Create list of node descriptors, one for each leaf obtained.
filteredNodeElements = filter(lambda element: not element.IsHint, nodeElementCollection)
nodeDescriptorArray = list(map(lambda element: DANodeDescriptor(element), filteredNodeElements))

# Get the value of DataType property; it is a 16-bit signed integer.
resultArray = IEasyDAClientExtension.GetMultiplePropertyValues(client,
                                                               serverDescriptor,
                                                               nodeDescriptorArray,
                                                               DAPropertyDescriptor.FromInt64(DAPropertyIds.DataType))
# Display results
for i, valueResult in enumerate(resultArray):
    nodeDescriptor = nodeDescriptorArray[i]
    # Check if there has been an error getting the property value.
    if valueResult.Exception is  None:
        # Convert the data type to VarType.
        varType = VarType(valueResult.Value)
        # Display the obtained data type.
        print(nodeDescriptor.ItemId, ': ', varType, sep='')
    else:
        print(nodeDescriptor.ItemId, ' *** Failure: ', valueResult.Exception.Message)

print()
print('Finished')
' This example shows how to obtain a data type of all OPC XML-DA items under a branch.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

Imports OpcLabs.BaseLib.ComInterop
Imports OpcLabs.BaseLib.OperationModel
Imports OpcLabs.EasyOpc
Imports OpcLabs.EasyOpc.DataAccess

Namespace DataAccess.Xml
    Friend Class GetMultiplePropertyValues
        Public Shared Sub DataTypeXml()
            Dim client = New EasyDAClient()
            Dim serverDescriptor As ServerDescriptor = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx"

            ' Browse for all leaves under the "Simulation" branch
            Dim nodeElementCollection = client.BrowseLeaves(serverDescriptor, "Static/Analog Types")

            ' Create list of node descriptors, one for each leaf obtained
            ' filter out hint leafs that do not represent real OPC items (rare)
            Dim nodeDescriptorArray() As DANodeDescriptor = nodeElementCollection _
                .Where(Function(element) Not element.IsHint) _
                .Select(Function(element) New DANodeDescriptor(element)) _
                .ToArray()

            ' Get the value of DataType property; it is a 16-bit signed integer
            Dim valueResultArray() As ValueResult = client.GetMultiplePropertyValues(serverDescriptor,
                    nodeDescriptorArray, DAPropertyIds.DataType)

            For i = 0 To valueResultArray.Length - 1
                Dim nodeDescriptor = nodeDescriptorArray(i)

                ' Check if there has been an error getting the property value
                Dim valueResult As ValueResult = valueResultArray(i)
                If valueResult.Exception IsNot Nothing Then
                    Console.WriteLine("{0} *** Failure: {1}", nodeDescriptor.NodeId, valueResult.Exception.Message)
                    Continue For
                End If

                ' Convert the data type to VarType
                Dim varType = CType(CShort(valueResult.Value), VarType)

                ' Display the obtained data type
                Console.WriteLine("{0}: {1}", nodeDescriptor.ItemId, varType)
            Next i
        End Sub
    End Class
End Namespace

COM

// This example shows how to obtain a data type of all OPC XML-DA items under a branch.
//
// Find all latest examples here : https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

class procedure GetMultiplePropertyValues.DataTypeXml;
var
  Arguments: OleVariant;
  BrowseParameters: _DABrowseParameters;
  Client: OpcLabs_EasyOpcClassic_TLB._EasyDAClient;
  Count: Cardinal;
  Element: OleVariant;
  I: Cardinal;
  PropertyArguments: _DAPropertyArguments;
  ServerDescriptor: _ServerDescriptor;
  NodeDescriptor: _DANodeDescriptor;
//  NodeDescriptorArray: Array of DANodeDescriptor;
  NodeElement: _DANodeElement;
  NodeElementCollection: _DANodeElementCollection;
  NodeElementEnumerator: IEnumVariant;
  ValueResult: _ValueResult;
  ValueResultArray: OleVariant;
  VarType: _VarType;
begin
  ServerDescriptor := CoServerDescriptor.Create;
  ServerDescriptor.UrlString := 'http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx';

  NodeDescriptor := CoDANodeDescriptor.Create;
  NodeDescriptor.ItemId := 'Static/Analog Types';

  BrowseParameters := CoDABrowseParameters.Create;
  BrowseParameters.BrowseFilter := DABrowseFilter_Leaves;

  // Instantiate the client object
  Client := CoEasyDAClient.Create;

  // Browse for all leaves under the "Static/Analog Types" branch
  NodeElementCollection := Client.BrowseNodes(
      ServerDescriptor,
      NodeDescriptor,
      BrowseParameters);


  // Create list of node descriptors, one for aeach leaf obtained
  I := 0;
  Arguments := VarArrayCreate([0, NodeElementCollection.Count - 1], varVariant);
  NodeElementEnumerator := NodeElementCollection.GetEnumerator;
  while (NodeElementEnumerator.Next(1, Element, Count) = S_OK) do
  begin
    NodeElement := IUnknown(Element) as _DANodeElement;
    // filter out hint leafs that do not represent real OPC XML-DA items (rare)
    if Not NodeElement.IsHint then
    begin
      PropertyArguments := CoDAPropertyArguments.Create;
      PropertyArguments.ServerDescriptor := ServerDescriptor;
      PropertyArguments.NodeDescriptor := NodeElement.ToDANodeDescriptor;
      PropertyArguments.PropertyDescriptor.PropertyId.InternalValue := DAPropertyIds_DataType;
      Arguments[I] := PropertyArguments;
      I := I + 1;
    end;
  end;
//  SetLength(Arguments, I);

  // Get the value of DataType property; it is a 16-bit signed integer
  TVarData(ValueResultArray).VType := varArray or varVariant;
  TVarData(ValueResultArray).VArray := PVarArray(
    Client.GetMultiplePropertyValues(Arguments));

  // Display results
  for I := VarArrayLowBound(ValueResultArray, 1) to VarArrayHighBound(ValueResultArray, 1) do
  begin
      ValueResult := IInterface(ValueResultArray[I]) as _ValueResult;

      // Check if there has been an error getting the property value
      if ValueResult.Exception <> nil then
      begin
        WriteLn(Format('s *** Failures', [Arguments[I].NodeDescriptor.NodeId, ValueResult.Exception.Message]));
        Continue;
      end;

      // Convert the data type to VarType
      VarType := CoVarType.Create;
      VarType.InternalValue := ValueResult.Value;

      // Display the obtained data type
      WriteLn(Format('s: s', [Arguments[I].NodeDescriptor.NodeId, VarType.ToString]));
  end;
  VarClear(ValueResultArray);
  VarClear(Arguments);
end;
// This example shows how to obtain a data type of all OPC XML-DA items under a branch.
//
// Find all latest examples here : https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

const DABrowseFilter_Leaves = 3;
const DAPropertyIds_DataType = 1;

$ServerDescriptor = new COM("OpcLabs.EasyOpc.ServerDescriptor");
$ServerDescriptor->UrlString = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx";

$NodeDescriptor = new COM("OpcLabs.EasyOpc.DataAccess.DANodeDescriptor");
$NodeDescriptor->ItemID = "Static/Analog Types";

$BrowseParameters = new COM("OpcLabs.EasyOpc.DataAccess.DABrowseParameters");
$BrowseParameters->BrowseFilter = DABrowseFilter_Leaves;

$Client = new COM("OpcLabs.EasyOpc.DataAccess.EasyDAClient");

// Browse for all leaves under the "Static/Analog Types" branch
$NodeElementCollection = $Client->BrowseNodes($ServerDescriptor, $NodeDescriptor, $BrowseParameters)->ToList();

$PropertyArgumentArray = array();
for ($i = 0; $i < $NodeElementCollection->Count(); $i++)
{
    if (!($NodeElementCollection[$i]->IsHint)) // filter out hint leafs that do not represent real OPC items (rare)
    {
        $PropertyArguments = new COM("OpcLabs.EasyOpc.DataAccess.OperationModel.DAPropertyArguments");
        $PropertyArguments->ServerDescriptor = $ServerDescriptor;
        $PropertyArguments->NodeDescriptor = $NodeElementCollection[$i]->ToDANodeDescriptor();
        $PropertyArguments->PropertyDescriptor->PropertyId->InternalValue = DAPropertyIds_DataType;
        $PropertyArgumentArray[] = $PropertyArguments;
    }
}

// Get the value of DataType property; it is a 16-bit signed integer
$valueResultArray = $Client->GetMultiplePropertyValues($PropertyArgumentArray);

for ($i = 0; $i < count($valueResultArray); $i++)
{
    // Check if there has been an error getting the property value
    $valueResult = $valueResultArray[$i];
    if (!is_null($valueResult->Exception))
    {
        printf("[s]: *** Failures\n", $PropertyArgumentArray[$i]->NodeDescriptor->NodeId, $valueResults->Exception->Message);
        continue;
    }
    // Convert the data type to VarType
    $VarType = new COM("OpcLabs.BaseLib.ComInterop.VarType");
    $VarType->InternalValue = $valueResult->Value;

    // Display the obtained data type
    printf("[s]s\n", $PropertyArgumentArray[$i]->NodeDescriptor->NodeId, $VarType);
}
Rem This example shows how to obtain a data type of all OPC XML-DA items under a branch.
Rem
Rem Find all latest examples here : https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

Private Sub GetMultiplePropertyValues_DataTypeXml_Command_Click()
    OutputText = ""
    
    Dim serverDescriptor As New serverDescriptor
    serverDescriptor.UrlString = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx"

    Dim NodeDescriptor As New DANodeDescriptor
    NodeDescriptor.ItemId = "Static/Analog Types"
    
    Dim BrowseParameters As New DABrowseParameters
    BrowseParameters.BrowseFilter = DABrowseFilter_Leaves
    
    ' Instantiate the client object
    Dim client As New EasyDAClient

    ' Browse for all leaves under the "Static/Analog Types" branch
    Dim NodeElementCollection As DANodeElementCollection
    Set NodeElementCollection = client.BrowseNodes(serverDescriptor, NodeDescriptor, BrowseParameters)
    
    ' Create list of node descriptors, one for each leaf obtained
    Dim arguments()
    ReDim arguments(NodeElementCollection.Count)
    Dim i: i = 0
    Dim NodeElement: For Each NodeElement In NodeElementCollection
        ' filter out hint leafs that do not represent real OPC XML-DA items (rare)
        If Not NodeElement.IsHint Then
            Dim PropertyArguments As New DAPropertyArguments
            Set PropertyArguments.serverDescriptor = serverDescriptor
            Set PropertyArguments.NodeDescriptor = NodeElement.ToDANodeDescriptor
            PropertyArguments.PropertyDescriptor.PropertyId.NumericalValue = DAPropertyIds_DataType
            Set arguments(i) = PropertyArguments
            Set PropertyArguments = Nothing
            i = i + 1
        End If
    Next

    Dim propertyArgumentArray()
    ReDim propertyArgumentArray(i - 1)
    Dim j: For j = 0 To i - 1
        Set propertyArgumentArray(j) = arguments(j)
    Next

    ' Get the value of DataType property; it is a 16-bit signed integer
    Dim valueResultArray() As Variant
    valueResultArray = client.GetMultiplePropertyValues(propertyArgumentArray)

    ' Display results
    For j = 0 To i - 1
        Dim NodeDescriptor2 As DANodeDescriptor
        Set NodeDescriptor2 = propertyArgumentArray(j).NodeDescriptor
                
        Dim ValueResult As ValueResult: Set ValueResult = valueResultArray(j)
        ' Check if there has been an error getting the property value
        If Not ValueResult.Exception Is Nothing Then
            OutputText = OutputText & NodeDescriptor2.NodeId & " *** Failure: " & ValueResult.Exception.Message & vbCrLf
        Else
          ' Display the obtained data type
          Dim VarType As New VarType
          VarType.InternalValue = ValueResult.value
          OutputText = OutputText & NodeDescriptor2.NodeId & ": " & VarType & vbCrLf
        End If
    Next
End Sub
Rem This example shows how to obtain a data type of all OPC XML-DA items under a branch.
Rem
Rem Find all latest examples here : https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

Option Explicit

Const DABrowseFilter_Leaves = 3
Const DAPropertyIds_DataType = 1

Dim ServerDescriptor: Set ServerDescriptor = CreateObject("OpcLabs.EasyOpc.ServerDescriptor")
ServerDescriptor.UrlString = "http://opcxml.demo-this.com/XmlDaSampleServer/Service.asmx"

Dim NodeDescriptor: Set NodeDescriptor = CreateObject("OpcLabs.EasyOpc.DataAccess.DANodeDescriptor")
NodeDescriptor.ItemID = "Static/Analog Types"

Dim BrowseParameters: Set BrowseParameters = CreateObject("OpcLabs.EasyOpc.DataAccess.DABrowseParameters")
BrowseParameters.BrowseFilter = DABrowseFilter_Leaves

Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")

' Browse for all leaves under the "Static/Analog Types" branch
Dim NodeElementCollection: Set NodeElementCollection = client.BrowseNodes(serverDescriptor, nodeDescriptor, browseParameters)

' Create list of node descriptors, one for each leaf obtained
Dim arguments()
Redim arguments(nodeElementCollection.Count)
Dim i: i = 0
Dim NodeElement: For Each NodeElement In NodeElementCollection
    ' filter out hint leafs that do not represent real OPC XML-DA items (rare)
    If Not NodeElement.IsHint Then
    Dim PropertyArguments: Set PropertyArguments = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAPropertyArguments")
    PropertyArguments.ServerDescriptor = ServerDescriptor
    PropertyArguments.NodeDescriptor = NodeElement.ToDANodeDescriptor
        PropertyArguments.PropertyDescriptor.PropertyId.InternalValue = DAPropertyIds_DataType
    Set arguments(i) = PropertyArguments
    i = i + 1
    End If    
Next

Dim propertyArgumentArray()
ReDim propertyArgumentArray(i - 1)
Dim j: For j = 0 To i - 1
    Set propertyArgumentArray(j) = arguments(j)
Next

' Get the value of DataType property; it is a 16-bit signed integer
Dim valueResultArray: valueResultArray = client.GetMultiplePropertyValues(propertyArgumentArray)

For j = 0 To i - 1
    Dim NodeDescriptor2: Set NodeDescriptor2 = propertyArgumentArray(j).NodeDescriptor
    ' Check if there has been an error getting the property value
    If Not (valueResultArray(j).Exception Is Nothing) Then
        WScript.Echo NodeDescriptor2.NodeId & " *** Failure: " & valueResultArray(j).Exception.Message
    Else
        ' Display the obtained data type
        Dim VarType: Set VarType = CreateObject("OpcLabs.BaseLib.ComInterop.VarType")
        VarType.InternalValue = valueResultArray(j).Value
        WScript.Echo nodeDescriptor2.NodeId & ": " & VarType
    End If
Next

 

QuickOPC supports OPC XML-DA also on Linux and macOS.
See Also

Examples - OPC Data Access

Conceptual